#pragma once
#include <boost/date_time/posix_time/posix_time.hpp>
#include <odb/nullable.hxx>
#include <odb/core.hxx>

#pragma db object
class Student
{
public:
    Student() {}
    Student(uint64_t sn, const std::string& name, uint16_t age, uint32_t cid):
        sn_(sn), name_(name), age_(age), classes_id_(cid) {}

    void sn(uint64_t num) { sn_ = num; }
    uint64_t sn() { return sn_; }

    void name(const std::string& name) { name_ = name; }
    std::string name() { return name_; }

    void age(unsigned short num) { age_ = num; }
    odb::nullable<unsigned short> age() { return age_; }

    void classes_id(uint32_t cid) { classes_id_ = cid; }
    uint32_t classes_id() { return classes_id_; }

private:
    friend class odb::access;
    #pragma db id auto
    uint32_t id_;
    #pragma db unique
    uint64_t sn_;
    std::string name_;
    odb::nullable<uint16_t> age_;
    #pragma db index
    uint32_t classes_id_;
};

#pragma db object
class Classes
{
public:
    Classes() {}
    Classes(const std::string& name) : name_(name) {}
    void name(const std::string& name) { name_ = name; }
    std::string name() { return name_; }
private:
    friend class odb::access;
    #pragma db id auto
    uint32_t id_;
    std::string name_;
};

#pragma db view object(Student) \
                object(Classes = classes : Student::classes_id_ == classes::id_) \
                query((?))
struct classes_student 
{
    #pragma db column(Student::id_)
    uint32_t id;
    #pragma db column(Student::sn_)
    uint64_t sn;
    #pragma db column(Student::name_)
    std::string name;
    #pragma db column(Student::age_)
    odb::nullable<uint16_t>age;
    #pragma db column(classes::name_)
    std::string classes_name;
};


// 只查询学生姓名   
// (?) --- 外部调用时传入的过滤条件
#pragma db view object(Student)
struct all_name {
    #pragma db column(Student::name_)
    std::string name;
};

// odb -d mysql --std c++11 --generate-query --generate-schema --profile boost/date-time student.hxx